package com.example.redisson.redisson;

import jakarta.annotation.Resource;
import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient;

import java.time.Duration;

public class SemaphoreService {

    @Resource
    private RedissonClient redissonClient;

    // 信号量
    public void semaphore() {
        // 获取分布式信号量，默认值为 0
        RSemaphore semaphore = redissonClient.getSemaphore("mySemaphore");

        // 设置信号量的最大许可数量
        semaphore.trySetPermits(3);

        // 创建多个线程来模拟并发访问
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                try {
                    // 在1秒内尝试获取许可, 如果获取成功, 执行临界区内的代码, 否则失败
                    boolean acquired = semaphore.tryAcquire(1, Duration.ofSeconds(1));
                    if (acquired) {
                        System.out.println(Thread.currentThread().getName() + " 获得信号量许可证.");
                        // 执行临界区内的代码
                        System.out.println(Thread.currentThread().getName() + " 执行关键部分...");
                        // 模拟一些耗时操作
                        Thread.sleep(2000);
                        // 释放许可
                        semaphore.release();
                        System.out.println(Thread.currentThread().getName() + " 释放信号量许可证.");
                    } else {
                        System.out.println(Thread.currentThread().getName() + " 未能获得信号量许可证.");
                    }
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    throw new RuntimeException(e);
                }
            }).start();
        }

        // 等待所有线程完成
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException(e);
        }
    }

}

// Redisson 提供了分布式信号量 (RSemaphore) 的实现，用于控制对有限数量资源的访问。信号量是一种常用的同步工具，用于限制同一时刻可以访问共享资源的线程数量。
// 在分布式系统中，这种功能尤为重要，因为它可以帮助确保在多个节点之间合理分配资源，避免资源过载。
/*
主要用途：
    资源限流:
        控制对共享资源的并发访问数量。
        例如，限制对某个服务接口的并发调用次数。
    任务调度:
        控制同时执行的任务数量。
        例如，在分布式爬虫中限制同时抓取网页的数量。
    并发控制:
        限制并发执行的线程数量。
        例如，在分布式数据库连接池中限制最大连接数。
*/